package net.pws.oos.biz.query.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import net.pws.common.util.DateUtils;
import net.pws.common.persistence.Page;
import net.pws.common.persistence.QueryRepository;
import net.pws.oos.biz.model.Notice;
import net.pws.oos.biz.model.NoticeReceiver;
import net.pws.oos.biz.model.Organization;
import net.pws.oos.biz.query.NoticeFinder;
import net.pws.oos.biz.query.parameter.NoticeQueryParameter;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

@Service
@SuppressWarnings({ "rawtypes", "unchecked" })
public class DefaultNoticeFinder extends AbstractFinder implements NoticeFinder {

	public Notice getNotice(String id) {
		String hql = QueryRepository.getInstance().get("hql.getNotice");
		return (Notice) entityManager.findFirst(hql, new Object[] { id });
	}

	public int myCount(NoticeQueryParameter queryParameter) {
		StringBuilder sql = new StringBuilder(QueryRepository.getInstance()
				.get("sql.countMyNotice"));
		List<Object> params = new ArrayList<Object>();
		params.add(queryParameter.getReceiverId());
		buildMyQuery(sql, null, params, queryParameter);
		Map map = (Map) entityManager.nativeFindFirst(sql.toString(),
				params.toArray());
		return ((Number) map.get("recordCount")).intValue();
	}

	public List<Map> myList(NoticeQueryParameter queryParameter) {
		StringBuilder countSql = new StringBuilder(QueryRepository
				.getInstance().get("sql.countMyNotice"));
		StringBuilder sql = new StringBuilder(QueryRepository.getInstance()
				.get("sql.listMyNotice"));
		List<Object> params = new ArrayList<Object>();
		params.add(queryParameter.getReceiverId());
		buildMyQuery(sql, countSql, params, queryParameter);
		sql.append(" order by n.create_date desc");

		Page page = (Page) entityManager.nativeFindPage(countSql.toString(),
				sql.toString(), params.toArray(), queryParameter.getStart(),
				queryParameter.getLimit());
		return page.getData();
	}

	public int count(NoticeQueryParameter queryParameter) {
		StringBuilder sql = new StringBuilder(QueryRepository.getInstance()
				.get("sql.countNotice"));
		List<Object> params = new ArrayList<Object>();
		buildQuery(sql, null, params, queryParameter);

		Map map = (Map) entityManager.nativeFindFirst(sql.toString(),
				params.toArray());
		return ((Number) map.get("recordCount")).intValue();
	}

	public List<Map> list(NoticeQueryParameter queryParameter) {
		StringBuilder countSql = new StringBuilder(QueryRepository
				.getInstance().get("sql.countNotice"));
		StringBuilder sql = new StringBuilder(QueryRepository.getInstance()
				.get("sql.listNotice"));
		List<Object> params = new ArrayList<Object>();
		buildQuery(sql, countSql, params, queryParameter);
		sql.append(" order by n.create_date desc");

		Page page = (Page) entityManager.nativeFindPage(countSql.toString(),
				sql.toString(), params.toArray(), queryParameter.getStart(),
				queryParameter.getLimit());
		return page.getData();
	}

	public NoticeReceiver findReceiver(String noticeId, String userId) {
		String hql = "from NoticeReceiver where readDate is null and notice.id=? and receiver.id=? ";
		return (NoticeReceiver) entityManager.findFirst(hql, new Object[] {
				noticeId, userId });
	}

	private void buildMyQuery(StringBuilder sql, StringBuilder sql2,
			List<Object> params, NoticeQueryParameter queryParameter) {
		if (sql == null || queryParameter == null) {
			return;
		}
		if (sql2 == null) {
			sql2 = new StringBuilder();
		}

		Boolean read = queryParameter.getRead();
		if (read != null) {
			if (read) {
				sql.append(" and r.read_date is not null ");
				sql2.append(" and r.read_date is not null ");
			} else {
				sql.append(" and r.read_date is null ");
				sql2.append(" and r.read_date is null ");
			}
		}

		// 创建时间
		if (queryParameter.getCreateStartDate() != null) {
			sql.append(" and n.create_date>=? ");
			sql2.append(" and n.create_date>=? ");
			params.add(queryParameter.getCreateStartDate());
		}
		if (queryParameter.getCreateEndDate() != null) {
			sql.append(" and n.create_date<? ");
			sql2.append(" and n.create_date<? ");
			params.add(DateUtils.addDay(queryParameter.getCreateEndDate(), 1));
		}
	}

	private void buildQuery(StringBuilder sql, StringBuilder sql2,
			List<Object> params, NoticeQueryParameter queryParameter) {
		if (sql == null || params == null || queryParameter == null) {
			return;
		}
		if (sql2 == null) {
			sql2 = new StringBuilder();
		}

		if (StringUtils.isNotBlank(queryParameter.getName())) {
			sql.append(" and n.name like ? ");
			sql2.append(" and n.name like ? ");
			params.add("%" + queryParameter.getName() + "%");
		}

		if (StringUtils.isNotBlank(queryParameter.getCreatorId())) {
			sql.append("and n.creator_id=? ");
			sql2.append("and n.creator_id=? ");
			params.add(queryParameter.getCreatorId());
		}

		if (StringUtils.isNotBlank(queryParameter.getOrganId())) {
			Organization org = entityManager.find(Organization.class,
					queryParameter.getOrganId());
			if (org != null) {
				sql.append(" and o.inner_code like ?");
				sql2.append(" and o.inner_code like ?");
				params.add(org.getInnerCode() + "%");
			}
		}

		// 创建时间
		if (queryParameter.getCreateStartDate() != null) {
			sql.append(" and n.create_date>=? ");
			sql2.append(" and n.create_date>=? ");
			params.add(queryParameter.getCreateStartDate());
		}
		if (queryParameter.getCreateEndDate() != null) {
			sql.append(" and n.create_date<? ");
			sql2.append(" and n.create_date<? ");
			params.add(DateUtils.addDay(queryParameter.getCreateEndDate(), 1));
		}
	}

	public List<Map> listReceivers(String noticeId) {
		String hql = QueryRepository.getInstance().get("hql.listReceivers");
		return entityManager.findList(hql, new Object[] { noticeId });
	}

}
